/*:
 * @plugindesc patch to Sleipnir Mapping Overlay System.js
 * @author 老饕
 * @date 2020.3.24
 *  
 * @param Animation Flag
 * @desc 动态图片标志
 * @default Ani
 *
 * @param Frame Flag
 * @desc 帧数标志
 * @default _frame
 *
 * @param Frame Rate
 * @type number
 * @desc 刷新帧率
 * @default 30
 *
 * @help
 * 本插件是Sleipnir Mapping Overlay System的补丁。
 * 补充在地图注释里配置雾
 * 地图标签
 * <Fog: name, opacity, scrollx, scrolly, blendMode>
 * 支持动态场景（远景、地面、遮罩）
 * 文件名格式：
 * 文件名Ani(帧序号)-F(总帧数)
 * 
 * 插件指令：
 * ChangeMap Parallax x
 * ChangeMap GroundLayer x
 * ChangeMap Overhead x
 * x：文件名，静态动态均可
 * 移动端尚未测试可能存在问题

*/

var SWDA_MapPatch = SWDA_MapPatch || {};

var parameters = PluginManager.parameters('patch_MapOverlay');
SWDA_MapPatch.aniFlag = String(parameters['Animation Flag'] || 'Ani');	// 动画标志
SWDA_MapPatch.frameFlag = String(parameters['Frame Flag'] || '-F');	// 帧数标志
SWDA_MapPatch.aniRate = Number(parameters['Frame Rate']) || 30;	// 刷新帧率

//===============================================================
// 修正创建雾时混合模式错误的问题
//===============================================================
SWDA_MapPatch.scene_map_start = Scene_Map.prototype.start;
Scene_Map.prototype.start = function () {
	SWDA_MapPatch.scene_map_start.call(this);

	if ($dataMap.meta["Fog"]) {
		const data = $dataMap.meta["Fog"].split(",");
		const name = data[0].trim();
		const opacity = Number(data[1]);
		const scrollx = Number(data[2]);
		const scrolly = Number(data[3]);
		const blendMode = Number(data[4]);
		$gameSystem.initializeFog(name, opacity, scrollx, scrolly, blendMode);
	} else {
		$gameSystem.fogName = null;
	}
};
//===============================================================
// 更新雾的移动模式（跟随地图运动）
//===============================================================
SWDA_MapPatch.game_map_scrollDown = Game_Map.prototype.scrollDown;
SWDA_MapPatch.game_map_scrollLeft = Game_Map.prototype.scrollLeft;
SWDA_MapPatch.game_map_scrollRight = Game_Map.prototype.scrollRight;
SWDA_MapPatch.game_map_scrollUp = Game_Map.prototype.scrollUp;

Game_Map.prototype.scrollDown = function (distance) {
	SWDA_MapPatch.game_map_scrollDown.call(this, distance);
	if (this.height() >= this.screenTileY()) {
		SceneManager._scene.fogImage.origin.y += ((this._displayY + distance + this.screenTileY()) < this.height() ? distance : 0) * this.tileHeight();
	}
};

Game_Map.prototype.scrollLeft = function (distance) {
	SWDA_MapPatch.game_map_scrollLeft.call(this, distance);
	if (this.width() >= this.screenTileX()) {
		SceneManager._scene.fogImage.origin.x -= ((this._displayX - distance) > 0 ? distance : 0) * this.tileWidth();
	}
};

Game_Map.prototype.scrollRight = function (distance) {
	SWDA_MapPatch.game_map_scrollRight.call(this, distance);
	if (this.width() >= this.screenTileX()) {
		SceneManager._scene.fogImage.origin.x += ((this._displayX + distance + this.screenTileX()) < this.width() ? distance : 0) * this.tileWidth();
	}

};

Game_Map.prototype.scrollUp = function (distance) {
	SWDA_MapPatch.game_map_scrollUp.call(this, distance);
	if (this.height() >= this.screenTileY()) {
		SceneManager._scene.fogImage.origin.y -= ((this._displayY - distance) > 0 ? distance : 0) * this.tileHeight();
	}
};

//===============================================================
// 支持动态场景
//===============================================================
//---------------------------------------------------------------
// Parallax Layer 远景层
//---------------------------------------------------------------
SWDA_MapPatch.Game_Map_Initialize = Game_Map.prototype.initialize;
Game_Map.prototype.initialize = function () {
	SWDA_MapPatch.Game_Map_Initialize.call(this);
	this._layer_aniCount = 0;
	this._parallax_frameID = 0;
};
// 是否显示动态地图
Spriteset_Map.prototype.isAnimatedMapEnabled = function(){
	return !Utils.isMobileDevice() && ConfigManager.animatedMap; // 移动端节省性能
}

// 补充：Parallax
SWDA_MapPatch.Spriteset_Map_CreateParallax = Spriteset_Map.prototype.createParallax;
Spriteset_Map.prototype.createParallax = function () {
	SWDA_MapPatch.Spriteset_Map_CreateParallax.call(this);

	const nameSplit = $gameMap.parallaxName().split(SWDA_MapPatch.aniFlag);
	this.isParallaxAnimated = (nameSplit.length > 1) && this.isAnimatedMapEnabled();
	this.parallaxFrameNum = Number($gameMap.parallaxName().split(SWDA_MapPatch.frameFlag)[1]);

	if (this.isParallaxAnimated) {
		for (ii = 0; ii < this.parallaxFrameNum; ii++) {
			const aniLayerName = nameSplit[0] + SWDA_MapPatch.aniFlag + ii + SWDA_MapPatch.frameFlag + this.parallaxFrameNum;
			ImageManager.reserveParallax(aniLayerName);	//读取所有地图帧？
		}
	}
};

Spriteset_Map.prototype.updateParallax = function () {
	let nameSplit = [$gameMap.parallaxName()];
	// 刷新帧ID
	if (this.isParallaxAnimated) {
		nameSplit = $gameMap.parallaxName().split(SWDA_MapPatch.aniFlag);
		if ($gameMap._layer_aniCount == SWDA_MapPatch.aniRate) {
			if ($gameMap._parallax_frameID + 1 >= this.parallaxFrameNum) {
				$gameMap._parallax_frameID = 0;
			} else {
				$gameMap._parallax_frameID += 1;
			}
		}
	}

	// 更新动态背景图
	if (this._parallaxName !== nameSplit[0]) {
		this._parallaxName = nameSplit[0];
		if (this._parallax.bitmap && Graphics.isWebGL() != true) {
			this._canvasReAddParallax();
		} else {
			if (this.isParallaxAnimated) {
				const aniLayerName = this._parallaxName + SWDA_MapPatch.aniFlag + '0' + SWDA_MapPatch.frameFlag + this.parallaxFrameNum;
				this._parallax.bitmap = ImageManager.requestParallax(aniLayerName);
			} else {
				this._parallax.bitmap = ImageManager.loadParallax(this._parallaxName);
			}
		}
	} else if (this.isParallaxAnimated & ($gameMap._layer_aniCount == SWDA_MapPatch.aniRate)) {
		var aniLayerName = this._parallaxName + SWDA_MapPatch.aniFlag + $gameMap._parallax_frameID + SWDA_MapPatch.frameFlag + this.parallaxFrameNum;
		this._parallax.bitmap = ImageManager.requestParallax(aniLayerName);
	}

	// 更新帧计数
	if (this.isParallaxAnimated || this.isGroundAnimated || this.isOverheadAnimated) {
		if ($gameMap._layer_aniCount === SWDA_MapPatch.aniRate) {
			$gameMap._layer_aniCount = 0;
		} else {
			$gameMap._layer_aniCount += 1;
		}
	}

	// （原有部分）
	if (this._parallax.bitmap) {
		this._parallax.origin.x = $gameMap.parallaxOx();
		this._parallax.origin.y = $gameMap.parallaxOy();
	}

};


//---------------------------------------------------------------
// Ground Layer 地面层
//---------------------------------------------------------------
SWDA_MapPatch.Game_Map_InitializeGroundLayer = Game_Map.prototype.initializeGroundLayer;
Game_Map.prototype.initializeGroundLayer = function () {
	SWDA_MapPatch.Game_Map_InitializeGroundLayer.call(this);
	this._layer_aniCount = 0;
	this._groundlayer_frameID = 0;
};
//补充：Ground Layer
SWDA_MapPatch.Spriteset_Map_CreateOverlaySprite = Spriteset_Map.prototype.createOverlaySprites;
Spriteset_Map.prototype.createOverlaySprites = function () {
	SWDA_MapPatch.Spriteset_Map_CreateOverlaySprite.call(this);

	var nameSplit = $gameMap.groundLayerName().split(SWDA_MapPatch.aniFlag);
	this.isGroundAnimated = ((nameSplit.length > 1) ? true : false) && this.isAnimatedMapEnabled();
	this.groundFrameNum = Number($gameMap.groundLayerName().split(SWDA_MapPatch.frameFlag)[1]);

	if (this.isGroundAnimated) {
		for (ii = 0; ii < this.groundFrameNum; ii++) {
			var aniLayerName = nameSplit[0] + SWDA_MapPatch.aniFlag + ii + SWDA_MapPatch.frameFlag + this.groundFrameNum;
			ImageManager.reserveOverlay(aniLayerName);	//读取所有地图帧？
		}
	}
};




Spriteset_Map.prototype.updateGroundLayer = function () {
	var nameSplit = [$gameMap.groundLayerName()];
	// 刷新帧ID
	if (this.isGroundAnimated) {
		nameSplit = $gameMap.groundLayerName().split(SWDA_MapPatch.aniFlag);
		if ($gameMap._layer_aniCount == SWDA_MapPatch.aniRate) {
			if ($gameMap._groundlayer_frameID + 1 >= this.groundFrameNum) {
				$gameMap._groundlayer_frameID = 0;
			} else {
				$gameMap._groundlayer_frameID += 1;
			}
		}
	}
	// 更新动态背景图
	if (this._groundlayerName !== nameSplit[0]) {
		this._groundlayerName = nameSplit[0];
		if (this.isGroundAnimated) {
			var aniLayerName = this._groundlayerName + SWDA_MapPatch.aniFlag + '0' + SWDA_MapPatch.frameFlag + this.groundFrameNum;
			this._groundlayer.bitmap = ImageManager.requestOverlay(aniLayerName);
		} else {
			this._groundlayer.bitmap = ImageManager.loadOverlay(this._groundlayerName);
		}
	} else if (this.isGroundAnimated & ($gameMap._layer_aniCount == SWDA_MapPatch.aniRate)) {
		var aniLayerName = this._groundlayerName + SWDA_MapPatch.aniFlag + $gameMap._groundlayer_frameID + SWDA_MapPatch.frameFlag + this.groundFrameNum;
		this._groundlayer.bitmap = ImageManager.requestOverlay(aniLayerName);
	}
	// 更新帧计数


	// （原有部分）
	this._groundlayer.x = - $gameMap.displayX() * $gameMap.tileWidth();
	this._groundlayer.y = - $gameMap.displayY() * $gameMap.tileWidth();
	this._groundlayer.opacity = parseInt($gameMap.groundLayerOpacity());

};





//---------------------------------------------------------------
// Overhead Layer 遮挡层
//---------------------------------------------------------------
SWDA_MapPatch.Game_Map_Initoverhead = Game_Map.prototype.initoverhead
Game_Map.prototype.initoverhead = function () {
	SWDA_MapPatch.Game_Map_Initoverhead.call(this);
	this._layer_aniCount = 0;
	this._overhead_frameID = 0;
};


// 补充：Overhead
SWDA_MapPatch.Spriteset_Map_CreateOverhead = Spriteset_Map.prototype.createoverhead;
Spriteset_Map.prototype.createoverhead = function () {
	SWDA_MapPatch.Spriteset_Map_CreateOverhead.call(this);

	const nameSplit = $gameMap.overheadName().split(SWDA_MapPatch.aniFlag);
	this.isOverheadAnimated = nameSplit.length > 1 && this.isAnimatedMapEnabled();

	this.overheadFrameNum = Number($gameMap.overheadName().split(SWDA_MapPatch.frameFlag)[1]);

	if (this.isOverheadAnimated) {
		for (ii = 0; ii < this.overheadFrameNum; ii++) {
			const aniLayerName = nameSplit[0] + SWDA_MapPatch.aniFlag + ii + SWDA_MapPatch.frameFlag + this.overheadFrameNum;
			ImageManager.reserveOverlay(aniLayerName);	//读取所有地图帧？
		}
	}
};

Spriteset_Map.prototype.updateoverhead = function () {
	let nameSplit = [$gameMap.overheadName()];
	// 刷新帧ID
	if (this.isOverheadAnimated) {
		nameSplit = $gameMap.overheadName().split(SWDA_MapPatch.aniFlag);
		if ($gameMap._layer_aniCount === SWDA_MapPatch.aniRate) {
			if ($gameMap._overhead_frameID + 1 >= this.overheadFrameNum) {
				$gameMap._overhead_frameID = 0;
			} else {
				$gameMap._overhead_frameID += 1;
			}
		}
	}

	// 更新动态背景图
	if (this._overheadName !== nameSplit[0]) {
		this._overheadName = nameSplit[0];
		if (this.isOverheadAnimated) {
			const aniLayerImageFileName = `${this._overheadName}${SWDA_MapPatch.aniFlag}0${SWDA_MapPatch.frameFlag}${this.overheadFrameNum}`
			this._overhead.bitmap = ImageManager.requestOverlay(aniLayerImageFileName);
		} else {
			this._overhead.bitmap = ImageManager.loadOverlay(this._overheadName);
		}
	} else if (this.isOverheadAnimated & ($gameMap._layer_aniCount === SWDA_MapPatch.aniRate)) {
		const aniLayerImageFileName = this._overheadName + SWDA_MapPatch.aniFlag + $gameMap._overhead_frameID + SWDA_MapPatch.frameFlag + this.overheadFrameNum;
		this._overhead.bitmap = ImageManager.requestOverlay(aniLayerImageFileName);
	}


	// （原有部分）
	if (this._overhead.bitmap) {
		this._overhead.origin.x = $gameMap.overheadOx();
		this._overhead.origin.y = $gameMap.overheadOy();
	}
};

//===============================================================
// 更新气泡显示层数
//===============================================================
SWDA_MapPatch.Sprite_Balloon_InitMember = Sprite_Balloon.prototype.initMembers;
Sprite_Balloon.prototype.initMembers = function () {
	SWDA_MapPatch.Sprite_Balloon_InitMember.call(this);
	this.z = 8;
};

//===============================================================
// 事件中的变更远景
//===============================================================

SWDA_MapPatch.command284 = Game_Interpreter.prototype.command284;
Game_Interpreter.prototype.command284 = function () {

	SWDA_MapPatch.command284.call(this);
	this.changeMapParallax(this._params[0]);
	return true;
};


//===============================================================
// 插件指令：变更场景图（远景、地面、遮挡）
//===============================================================
SWDA_MapPatch.PLUGIN_COMMAND = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function (command, args) {
	SWDA_MapPatch.PLUGIN_COMMAND.call(this, command, args);

	if (command == 'ChangeMap' && !$gameParty.inBattle()) {
		var mode = args[0].toUpperCase();	//PARALLAX/GROUND/OVERHEAD
		var fileName = args[1];
		switch (mode) {
			case "PARALLAX":
				this.changeMapParallax(fileName);
				break;
			case "GROUNDLAYER":
				this.changeMapGroundLayer(fileName);
				break;
			case "OVERHEAD":
				this.changeMapOverhead(fileName);
				break;
		}
	}
};

// 是否显示动态地图(事件触发)
Game_Interpreter.prototype.isAnimatedMapEnabled = function(){
	return !Utils.isMobileDevice() && ConfigManager.animatedMap;
}

Game_Interpreter.prototype.changeMapParallax = function (fileName) {
	$gameMap._parallaxName = fileName;
	$gameMap._parallaxZero = ImageManager.isZeroParallax($gameMap._parallaxName);
	var nameSplit = $gameMap.parallaxName().split(SWDA_MapPatch.aniFlag);
	SceneManager._scene._spriteset.isParallaxAnimated = ((nameSplit.length > 1) ? true : false) && this.isAnimatedMapEnabled();
	SceneManager._scene._spriteset.parallaxFrameNum = Number($gameMap.parallaxName().split(SWDA_MapPatch.frameFlag)[1]);

	if (SceneManager._scene._spriteset.isParallaxAnimated) {
		for (ii = 0; ii < SceneManager._scene._spriteset.parallaxFrameNum; ii++) {
			var aniLayerName = nameSplit[0] + SWDA_MapPatch.aniFlag + ii + SWDA_MapPatch.frameFlag + SceneManager._scene._spriteset.parallaxFrameNum;
			ImageManager.reserveParallax(aniLayerName);
		}
	}
}

Game_Interpreter.prototype.changeMapGroundLayer = function (fileName) {
	$gameMap._groundlayerName = fileName;
	$gameMap._groundlayerZero = ImageManager.isZeroGroundLayer($gameMap._groundlayerName);
	var nameSplit = $gameMap.groundLayerName().split(SWDA_MapPatch.aniFlag);
	SceneManager._scene._spriteset.isGroundAnimated = ((nameSplit.length > 1) ? true : false) && this.isAnimatedMapEnabled();
	SceneManager._scene._spriteset.groundFrameNum = Number($gameMap.groundLayerName().split(SWDA_MapPatch.frameFlag)[1]);

	if (SceneManager._scene._spriteset.isGroundAnimated) {
		for (ii = 0; ii < SceneManager._scene._spriteset.groundFrameNum; ii++) {
			var aniLayerName = nameSplit[0] + SWDA_MapPatch.aniFlag + ii + SWDA_MapPatch.frameFlag + SceneManager._scene._spriteset.groundFrameNum;
			ImageManager.reserveOverlay(aniLayerName);	//读取所有地图帧？
		}
	}
}

Game_Interpreter.prototype.changeMapOverhead = function (fileName) {
	$gameMap._overheadName = fileName;
	$gameMap._overheadZero = ImageManager.isZerooverhead($gameMap._overheadName);
	var nameSplit = $gameMap.overheadName().split(SWDA_MapPatch.aniFlag);
	SceneManager._scene._spriteset.isOverheadAnimated = ((nameSplit.length > 1) ? true : false) && this.isAnimatedMapEnabled();
	SceneManager._scene._spriteset.overheadFrameNum = Number($gameMap.overheadName().split(SWDA_MapPatch.frameFlag)[1]);

	if (SceneManager._scene._spriteset.isOverheadAnimated) {
		for (ii = 0; ii < SceneManager._scene._spriteset.overheadFrameNum; ii++) {
			var aniLayerName = nameSplit[0] + SWDA_MapPatch.aniFlag + ii + SWDA_MapPatch.frameFlag + SceneManager._scene._spriteset.overheadFrameNum;
			ImageManager.reserveOverlay(aniLayerName);	//读取所有地图帧？
		}
	}
}
